package com.email.box.common.vo;

import com.email.box.common.enums.DefaultApiResultCode;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.springframework.http.HttpMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.server.ServerWebExchange;

@ResponseBody
public class RespVO<T> {

    private int code;

    private String message;

    private Long count;

    @JsonInclude(Include.NON_NULL)
    private T data;

    @JsonIgnore
    private ApiResultCode apiResultCode;

    @JsonProperty("execute_time")
    @JsonInclude(Include.NON_NULL)
    private Long executeTime;

    private RespVO(){}

    private RespVO(ApiResultCode code, T data) {
        this.code = code.getCode();
        this.message = code.getMessage();
        this.data = data;
        this.apiResultCode = code;
        this.count = null;
    }

    private RespVO(ApiResultCode code, T data, Long count) {
        this.code = code.getCode();
        this.message = code.getMessage();
        this.data = data;
        this.apiResultCode = code;
        this.count = count;
    }

    private RespVO(ApiResultCode code, String msg, T data) {
        this.code = code.getCode();
        this.message = msg;
        this.data = data;
        this.apiResultCode = code;
        this.count = null;
    }

    public static <E> RespVO<E> success() {
        return new RespVO(DefaultApiResultCode.SUCCESS, (Object) null);
    }

    public static <E> RespVO<E> success(E data) {
        return new RespVO(DefaultApiResultCode.SUCCESS, data);
    }

    public static <E> RespVO<E> success(E data, Long count) {
        return new RespVO(DefaultApiResultCode.SUCCESS, data, count);
    }

    public static <E> RespVO<E> of(ApiResultCode respCode, String msg, E body) {
        return new RespVO(respCode, msg, body);
    }

    public static <E> RespVO<E> of(ApiResultCode apiResultCode, String msg) {
        return of(apiResultCode, msg, null);
    }

    public static <E> RespVO<E> failure(ApiResultCode apiResultCode, String msg) {
        return new RespVO(apiResultCode, msg, (Object) null);
    }

    public static <E> RespVO<E> failure(ApiResultCode apiResultCode) {
        return failure(apiResultCode, apiResultCode.getMessage());
    }

    public static <E> RespVO<E> serverError(String overrideDefaultMsg) {
        return new RespVO(DefaultApiResultCode.G500, overrideDefaultMsg, (Object) null);
    }

    public static <E> RespVO<E> serverError() {
        return new RespVO(DefaultApiResultCode.G500, (Object) null);
    }

    public static RespVO<Object> emptyResp(ServerWebExchange exchange) {
        return exchange.getRequest().getMethod() == HttpMethod.GET ? failure(ApiResultCode.G1001) : success();
    }

    public int getCode() {
        return code;
    }

    public String getMessage() {
        return message;
    }

    public Long getCount() {
        return count;
    }

    public T getData() {
        return data;
    }

    @JsonIgnore
    public ApiResultCode getApiResultCode() {
        return apiResultCode;
    }

    public Long getExecuteTime() {
        return executeTime;
    }

    public void setExecuteTime(Long executeTime) {
        this.executeTime = executeTime;
    }

    @JsonIgnore
    public boolean cacheable() {
        return this.getCode() == ApiResultCode.SUCCESS.getCode() || this.getCode() == ApiResultCode.G1001.getCode();
    }
}
